package com.zgw.fireline.design.edit;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.wb.core.model.JavaInfo;
import org.eclipse.wb.internal.core.DesignerPlugin;
import org.eclipse.wb.internal.core.model.JavaInfoEvaluationHelper;
import org.eclipse.wb.internal.core.model.JavaInfoUtils;
import org.eclipse.wb.internal.core.model.creation.ConstructorCreationSupport;
import org.eclipse.wb.internal.core.utils.jdt.ui.JdtUiUtils;
import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils;
import org.eclipse.wb.internal.core.utils.state.GlobalState;
import org.eclipse.wb.internal.core.utils.ui.GridDataFactory;
import org.eclipse.wb.internal.core.utils.ui.GridLayoutFactory;
import org.eclipse.wb.swt.SWTResourceManager;

import com.zgw.fireline.design.Model.BatchInfo;
import com.zgw.fireline.design.Model.BatchItemInfo;
import com.zgw.fireline.design.Model.DatasetCodeUtil;
import com.zgw.fireline.design.Model.IDataBaseProvideHelp;
import com.zgw.fireline.design.common.CodeStyleFactory;
import com.zgw.fireline.design.common.ExecutionUtils2;
import org.eclipse.swt.widgets.TreeColumn;

import syntaxcolor.v4.syntaxcolor.CodeStyleText;

/**
 * 批处理命令编辑管理窗口
 * */
public class BatchEditDialog extends Dialog {

	protected int result;
	protected Shell shell;
	private Text textDefineKey; // 数据源编号

	private Combo execProvideComb;// 数据源提供器
	private CodeStyleText textSql;
	private Text textParamEdit; // 参数编辑
	private Button btnCustom;
	private Button btnSys;
	private TabFolder tabFolder;
	private org.eclipse.swt.widgets.List paramGroupList;
	private Tree batchTree;
	private final BatchInfo batch;

	// ======================================
	// 业务数据
	// =======================================
	public List<BatchItemInfo> items;
	public Class<?> baseProvideClass; // 解析执行器类
	public boolean isSysDefine = false;
	private SelectionAdapter checkEnable;
	private TreeEditor treeEditor;

	/**
	 * Create the dialog.
	 * 
	 * @param parent
	 * @param style
	 */
	public BatchEditDialog(Shell parent, int style, BatchInfo batch) {
		super(parent, style);
		setText("SWT Dialog");
		this.batch = batch;
	}

	/**
	 * Open the dialog.
	 * 
	 * @return the result
	 */
	public int open() {
		createContents();
		shell.open();
		shell.layout();
		Display display = getParent().getDisplay();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return result;
	}

	/**
	 * Create contents of the dialog.
	 */
	private void createContents() {
		shell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.MAX
				| SWT.APPLICATION_MODAL);
		shell.setSize(606, 515);
		shell.setText("批处理编辑");

		GridLayout gl_shell = new GridLayout(1, false);
		gl_shell.verticalSpacing = 10;
		shell.setLayout(gl_shell);

		tabFolder = new TabFolder(shell, SWT.NONE);
		tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1,
				1));
		TabItem tbtmNewItem = new TabItem(tabFolder, SWT.NONE);
		tbtmNewItem.setText("基本信息");

		Composite composite = new Composite(tabFolder, SWT.NONE);
		tbtmNewItem.setControl(composite);
		GridLayout gl_composite = new GridLayout(1, false);
		gl_composite.verticalSpacing = 10;
		gl_composite.marginHeight = 10;
		composite.setLayout(gl_composite);

		Group group = new Group(composite, SWT.NONE);
		group.setLayout(new GridLayout(3, false));
		group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1,
				1));
		group.setText("解析执行器");

		CLabel lblNewLabel = new CLabel(group, SWT.NONE);
		lblNewLabel.setText("Class:");

		execProvideComb = new Combo(group, SWT.READ_ONLY);
		execProvideComb.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 1, 1));
		Button btnNewButton_1 = new Button(group, SWT.NONE);
		btnNewButton_1.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doSearchExecProvide();
			}
		});
		btnNewButton_1.setText("  &S查找...");

		Group group_3 = new Group(composite, SWT.NONE);
		group_3.setText("类别：");
		group_3.setLayout(new GridLayout(4, false));
		group_3.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				1, 1));

		btnCustom = new Button(group_3, SWT.RADIO);
		btnCustom.setText("自定义");

		btnSys = new Button(group_3, SWT.RADIO);
		btnSys.setText("系统定义：");

		textDefineKey = new Text(group_3, SWT.BORDER);
		textDefineKey.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 1, 1));

		final Button btnNewButton_11 = new Button(group_3, SWT.NONE);
		btnNewButton_11.setText("  选择... ");
		checkEnable = new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				boolean enabled = btnSys.getSelection();
				textDefineKey.setEnabled(enabled);
				btnNewButton_11.setEnabled(enabled);
			}
		};
		btnCustom.addSelectionListener(checkEnable);
		btnSys.addSelectionListener(checkEnable);
		checkEnable.widgetSelected(null);
		Group grpSql = new Group(composite, SWT.NONE);
		grpSql.setText("处理项");
		GridLayout gl_grpSql = new GridLayout(1, false);
		gl_grpSql.marginWidth = 0;
		gl_grpSql.marginHeight = 6;
		grpSql.setLayout(gl_grpSql);
		grpSql.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

		ToolBar toolBar = new ToolBar(grpSql, SWT.RIGHT);
		toolBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				1, 1));

		ToolItem tltmNewItem = new ToolItem(toolBar, SWT.NONE);
		tltmNewItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doAddBatchItem();
			}
		});
		tltmNewItem.setText("添加");

		ToolItem tltmNewItem_4 = new ToolItem(toolBar, SWT.NONE);
		tltmNewItem_4.setText("引入");

		ToolItem tltmNewItem_2 = new ToolItem(toolBar, SWT.NONE);
		tltmNewItem_2.setText("上移");
		tltmNewItem_2.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doMoveItem(-1);
			}
		});

		ToolItem tltmNewItem_3 = new ToolItem(toolBar, SWT.NONE);
		tltmNewItem_3.setText("下移");
		tltmNewItem_3.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doMoveItem(+1);
			}
		});

		ToolItem tltmNewItem_1 = new ToolItem(toolBar, SWT.NONE);
		tltmNewItem_1.setText("移除");
		tltmNewItem_1.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doRemoveBatchItem();
			}
		});

		SashForm sashForm = new SashForm(grpSql, SWT.NONE);
		sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1,
				1));

		batchTree = new Tree(sashForm, SWT.BORDER | SWT.FULL_SELECTION);
		batchTree.setLinesVisible(true);
		// batchTree.setHeaderVisible(true);
		batchTree.addListener(SWT.MeasureItem, new Listener() {
			public void handleEvent(Event event) {
				event.height = 20;
			}
		});

		// ==========================================
		// 参数编辑
		// ===========================================
		final Composite paramEdit = new Composite(batchTree, SWT.NONE);
		GridLayoutFactory.create(paramEdit).columns(2).noSpacing().marginsH(4)
				.marginsV(0);

		textParamEdit = new Text(paramEdit, SWT.NONE);
		textParamEdit.setBackground(SWTResourceManager.getColor(232, 242, 254));
		GridDataFactory.create(textParamEdit).grabV().grabH().fillH();
		Button btnSelected = new Button(paramEdit, SWT.ARROW);
		btnSelected.setText("...");
		btnSelected.setToolTipText("选择参数值");
		btnSelected.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doSetParamValue();
			}
		});
		treeEditor = new TreeEditor(batchTree);
		treeEditor.grabHorizontal = true;
		treeEditor.grabVertical = true;
		treeEditor.setEditor(paramEdit);
		paramEdit.setBackground(textParamEdit.getBackground());
		Menu menu_1 = new Menu(batchTree);
		batchTree.setMenu(menu_1);

		MenuItem mntmNewItem_4 = new MenuItem(menu_1, SWT.NONE);
		mntmNewItem_4.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doAddParam();
			}
		});
		mntmNewItem_4.setText("新增参数&A");

		new MenuItem(menu_1, SWT.SEPARATOR);

		MenuItem mntmNewItem_6 = new MenuItem(menu_1, SWT.NONE);
		mntmNewItem_6.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doMoveParam(-1);
			}
		});
		mntmNewItem_6.setText("参数上移&U");
		MenuItem mntmNewItem_7 = new MenuItem(menu_1, SWT.NONE);
		mntmNewItem_7.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doMoveParam(1);
			}
		});
		mntmNewItem_7.setText("参数下移&U");
		new MenuItem(menu_1, SWT.SEPARATOR);

		MenuItem mntmNewItem_5 = new MenuItem(menu_1, SWT.NONE);
		mntmNewItem_5.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doRemoveParam();
			}
		});
		mntmNewItem_5.setText("删除参数&D");

		TreeColumn trclmnNewColumn = new TreeColumn(batchTree, SWT.NONE);
		trclmnNewColumn.setWidth(30);
		trclmnNewColumn.setText("序号");

		TreeColumn trclmnNewColumn_1 = new TreeColumn(batchTree, SWT.NONE);
		trclmnNewColumn_1.setWidth(100);
		trclmnNewColumn_1.setText("名称/值");
		textSql = new CodeStyleText(sashForm, SWT.BORDER | SWT.V_SCROLL
				| SWT.MULTI);
		textSql.setFont(SWTResourceManager.getFont("Courier New", 10,
				SWT.NORMAL));

		Menu menu = new Menu(textSql);
		textSql.setMenu(menu);

		MenuItem mntmNewItem = new MenuItem(menu, SWT.NONE);
		mntmNewItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (baseProvideClass == null) {
					MessageDialog.openInformation(shell, "提示", "未指定解析器");
					return;
				}
				// 获取当前处理项
				if (batchTree.getSelectionCount() <= 0) {
					return;
				}
				TreeItem item = batchTree.getSelection()[0];
				TreeItem parent = item.getParentItem() == null ? item : item
						.getParentItem();
				if (parent.getItemCount() >= 0) {
					if (!MessageDialog.openQuestion(shell, "提示",
							"将会覆盖已设置的参数，是否继续?")) {
						return;
					}
				}
				try {
					int count = IDataBaseProvideHelp.getParamCount(
							baseProvideClass, textSql.getText());
					parent.removeAll();
					for (int i = 0; i < count; i++) {
						new TreeItem(parent, SWT.NONE);
					}
					parent.setExpanded(true);
					paramEdit.setVisible(false);
				} catch (Exception e1) {
					ExecutionUtils2.openErrorDialog("生成参数失败", e1);
				}
			}
		});
		mntmNewItem.setText("生成参数&B");
		StyleRange range = new StyleRange();
		range.font = textSql.getFont();
		textSql.addRule(CodeStyleFactory.buildSqlRules(range));
		sashForm.setWeights(new int[] { 154, 409 });

		// tableCursor.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
		Label label = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1,
				1));

		Composite composite_5 = new Composite(shell, SWT.NONE);
		RowLayout rl_composite_5 = new RowLayout(SWT.HORIZONTAL);
		rl_composite_5.pack = false;
		composite_5.setLayout(rl_composite_5);
		composite_5.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));

		Button btnNewButton = new Button(composite_5, SWT.NONE);
		btnNewButton.setText("&P预览数据");

		Button btnNewButton_10 = new Button(composite_5, SWT.NONE);
		btnNewButton_10.setText("   &O确定   ");
		btnNewButton_10.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				okPressed();
			}
		});
		Button btnNewButton_9 = new Button(composite_5, SWT.NONE);
		btnNewButton_9.setText("&C取消");
		btnNewButton_9.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				cancel();
			}
		});
		initializeListener();
		initializeData();
	}

	// 调整处理项执行顺序
	protected void doMoveItem(int amount) {
		if (batchTree.getSelectionCount() <= 0
				|| batchTree.getSelection()[0].getParentItem() != null) {
			return;
		}

		batchTree.setVisible(false);
		int index = batchTree.indexOf(batchTree.getSelection()[0]);
		int index2 = index + amount;
		if (index2 >= 0 && index2 < batchTree.getItemCount()) {
			TreeItem item1 = batchTree.getItem(index);
			TreeItem item2 = batchTree.getItem(index2);
			String text1 = item1.getText(1);
			Object data1 = item1.getData();
			TreeItem[] children1 = item1.getItems();

			// 将item2参数节点移至 item1
			for (TreeItem child2 : item2.getItems()) {
				TreeItem child = new TreeItem(item1, SWT.NONE);
				String text = child2.getText(1);
				child.setText(1, text);
				child.setData(text, child2.getData(text));
				child2.dispose();
			}
			// 将item1参数节点移至 item2
			for (TreeItem child1 : children1) {
				TreeItem child = new TreeItem(item2, SWT.NONE);
				String text = child1.getText(1);
				child.setText(1, text);
				child.setData(text, child1.getData(text));
				child1.dispose();
			}

			item1.setText(1, item2.getText(1));
			item1.setData(item2.getData());
			item2.setText(1, text1);
			item2.setData(data1);
			batchTree.setSelection(item2);
			batchTree.setSelection(item2);
		}
		batchTree.setVisible(true);
		batchTree.layout(true);
		// 移动参数项
	}

	protected void doMoveParam(int amount) {
		if (batchTree.getSelectionCount() <= 0
				|| batchTree.getSelection()[0].getData() instanceof BatchItemInfo) {
			return;
		}
		TreeItem item1 = batchTree.getSelection()[0];
		TreeItem parent = item1.getParentItem();
		int index = parent.indexOf(item1);
		int index2 = index + amount;
		if (index2 >= 0 && index2 < item1.getParentItem().getItemCount()) {
			TreeItem item2 = parent.getItem(index2);
			String text1 = item1.getText(1);
			Object data1 = item1.getData(item1.getText(1));
			item1.setText(1, item2.getText(1));
			item1.setData(item2.getText(1), item2.getData(item2.getText(1)));
			item2.setText(1, text1);
			item2.setData(text1, data1);
			batchTree.setSelection(item2);
			activateParamEdit();
			textParamEdit.setFocus();
		}

	}

	private void initializeData() {
		baseProvideClass = batch.getProvideClass();
		isSysDefine = batch.isSysDefine();
		if (baseProvideClass != null)
			setProvideClassText(baseProvideClass.getSimpleName());
		else {
			try {
				baseProvideClass = IDataBaseProvideHelp
						.getDefaultProvideClass();
				setProvideClassText(baseProvideClass.getName());
			} catch (Exception e) {
				ExecutionUtils2.openErrorDialog("加载默认解析器失败", e);
			}
		}
		btnCustom.setSelection(!isSysDefine);
		btnSys.setSelection(isSysDefine);
		checkEnable.widgetSelected(null);

		String signature = ReflectionUtils.getMethodSignature("setParam",
				new Class[] { int.class, int.class, Object.class });
		List<MethodInvocation> list = batch.getMethodInvocations(signature);
		items = batch.getChildren(BatchItemInfo.class);
		int index = 0;
		ArrayList<Param> params;

		// ================初始化 处理项参数和属性
		for (BatchItemInfo item : items) {
			item.refreshProperty(); // 刷新属性值
			index = items.indexOf(item);
			params = new ArrayList<Param>();
			for (MethodInvocation invo : list) { // 刷新参数值
				invo.arguments().get(0);
				int cIndex = (Integer) JavaInfoEvaluationHelper
						.getValue((Expression) invo.arguments().get(0));
				int pIndex = (Integer) JavaInfoEvaluationHelper
						.getValue((Expression) invo.arguments().get(1));
				Object argument3 = invo.arguments().get(2);
				if (index == cIndex) {
					params.ensureCapacity(pIndex);
					while (params.size() <= pIndex) {
						params.add(null);
					}
					Param param = new Param();
					if (argument3 instanceof MethodInvocation) {
						JavaInfo target = batch.getRootJava()
								.getChildRepresentedBy(
										((MethodInvocation) argument3)
												.getExpression());
						if (target != null) {
							param.target = target;
							String mp = argument3.toString();
							param.signature = mp.substring(mp.indexOf(".") + 1);
						}
					} else {
						Object value = JavaInfoEvaluationHelper
								.getValue((Expression) argument3);
						param.value = value;
					}
					params.set(pIndex, param);
				}
			}
			item.setParams(params.toArray(new Param[params.size()]));
		}
		// ==============构建处理项树

		for (BatchItemInfo i : items) {
			TreeItem parent = new TreeItem(batchTree, SWT.NONE);
			parent.setFont(SWTResourceManager.getFont("宋体", 9, SWT.BOLD));
			parent.setText(1, i.getName());
			parent.setData(i);
			int k = -1;
			for (Param p : i.getParams()) {
				k++;
				TreeItem children = new TreeItem(parent, SWT.NONE);
				if (p != null) {
					children.setText(1, p.toString());
					children.setData(children.getText(1), p);
				} else {
					children.setText(k + " ");
				}
			}
		}
	}

	private void initializeListener() {
		// 设置处理项命令
		textSql.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				if (batchTree.getSelectionCount() <= 0) {
					return;
				}
				TreeItem item = batchTree.getSelection()[0];
				TreeItem parent = item.getParentItem() == null ? item : item
						.getParentItem();
				BatchItemInfo obj = (BatchItemInfo) parent.getData();
				obj.setCommand(textSql.getText());
			}
		});
		batchTree.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (batchTree.getSelectionCount() <= 0) {
					return;
				}
				Object obj = batchTree.getSelection()[0].getData();
				BatchItemInfo iteminfo = null;
				if (obj instanceof BatchItemInfo) {
					iteminfo = (BatchItemInfo) obj;
					String cmd = iteminfo.getCommand();
					if (!textSql.getText().equals(cmd))
						textSql.setText(cmd == null ? "" : cmd);
					textSql.setText(cmd == null ? "" : cmd);
					treeEditor.getEditor().setVisible(false);
				} else {// 参数项
					iteminfo = (BatchItemInfo) batchTree.getSelection()[0]
							.getParentItem().getData();
					String cmd = iteminfo.getCommand();
					if (!textSql.getText().equals(cmd))
						textSql.setText(cmd == null ? "" : cmd);
					activateParamEdit();
					textParamEdit.setFocus();
				}
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				if (batchTree.getSelectionCount() <= 0) {
					return;
				}
				TreeItem item = batchTree.getSelection()[0];
				BatchItemInfo info = (BatchItemInfo) item.getData();
				if (info instanceof BatchItemInfo) {
					InputDialog dlg = new InputDialog(shell, "编辑处理项",
							"处理项名称描述", info.getName(), new IInputValidator() {
								public String isValid(String newText) {
									if ("".equals(newText)) {
										return "请输入名称";
									}
									for (TreeItem ti : batchTree.getItems()) {
										if (ti.getText().equals(newText)) {
											return "名称不能重复";
										}
									}
									return null;
								}
							});
					if (dlg.open() == dlg.OK) {
						item.setText(1, dlg.getValue());
						info.setName(dlg.getValue());
					}
				}
			}
		});
		batchTree.addListener(SWT.EraseItem, new Listener() {
			public void handleEvent(Event event) {
				Rectangle bounds = event.getBounds();
				TreeItem item = (TreeItem) event.item;
				if (event.index == 0 && item.getParentItem() != null) {
					Color oldBackground = event.gc.getBackground();
					if ((event.detail & SWT.SELECTED) == 0) {
						event.gc.setBackground(event.item.getDisplay()
								.getSystemColor(SWT.COLOR_GRAY));
					} else {
						event.gc.setBackground(event.item.getDisplay()
								.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));

					}
					event.gc.fillRectangle(bounds);
					String index = "";
					if (item.getParentItem() != null) {
						index = item.getParentItem().indexOf(item) + "";
						event.detail &= ~SWT.SELECTED;
					}
					event.gc.drawString(index + "", bounds.x + 9, bounds.y + 4);
					event.gc.setBackground(oldBackground);
				}
			}
		});

		batchTree.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				if (batchTree.getItemCount() <= 0)
					return;
				int width = 0;
				for (TreeColumn c : batchTree.getColumns()) {
					width += c.getWidth();
				}
				Rectangle bounds = null;
				for (TreeItem item : batchTree.getItems()) {
					bounds = item.getBounds(0);
					e.gc.drawLine(0, bounds.y + bounds.height, width, bounds.y
							+ bounds.height);
					if (item.getExpanded()) {
						for (TreeItem child : item.getItems()) {
							bounds = child.getBounds(0);
							e.gc.drawLine(0, bounds.y + bounds.height, width,
									bounds.y + bounds.height);
						}
					}

				}
				width = 0;
				for (TreeColumn c : batchTree.getColumns()) {
					width += c.getWidth();
					if (batchTree.indexOf(c) == 0)
						e.gc.drawLine(width - 2, 0, width - 2, bounds.y
								+ bounds.height);
					else
						e.gc.drawLine(width, 0, width, bounds.y + bounds.height);
				}
				if (batchTree.getSelection().length > 0) {
					Color old = e.gc.getForeground();
					e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_RED));
					Rectangle b = batchTree.getSelection()[0].getBounds(0);
					e.gc.drawLine(0, b.y + b.height, width, b.y + b.height);
					e.gc.setForeground(old);
				}
			}
		});
		textParamEdit.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				if (treeEditor.getItem() != null)
					treeEditor.getItem().setText(1, textParamEdit.getText());
			}
		});
		batchTree.addControlListener(new ControlAdapter() {
			@Override
			public void controlResized(ControlEvent e) {
				int width0 = batchTree.getColumn(0).getWidth();
				int width1 = batchTree.getSize().x;
				if (batchTree.getVerticalBar().isVisible()) {
					batchTree.getColumn(1).setWidth(width1 - width0 - 25);
				} else {
					batchTree.getColumn(1).setWidth(width1 - width0 - 5);
				}
			}
		});
		Listener textSqlListener = new Listener() {
			public void handleEvent(Event e) {
				textSql.setToolTipText("");
				// 显示设置的指针 cursor
				int offset = -1;
				try {
					offset = textSql.getOffsetAtLocation(new Point(e.x, +e.y));
				} catch (Exception e1) {
					return;
				}
				if (offset < 0 || offset >= textSql.getCharCount()) {
					return;
				}
				StyleRange range = textSql.getStyleRangeAtOffset(offset);
				if (range == null)
					return;
				List<StyleRange> ranges = textSql
						.getStyleRangeByRule("placeSign");
				int index = -1;
				for (StyleRange r : ranges) {
					if (r.start == range.start && r.length == range.length) {
						index = ranges.indexOf(r);
						break;
					}
				}
				if (batchTree.getSelectionCount() <= 0)
					return;
				TreeItem selected = batchTree.getSelection()[0];
				TreeItem parent = selected.getParentItem() == null ? selected
						: selected.getParentItem();
				if (index < 0 || index >= parent.getItemCount()) {
					return;
				}
				TreeItem item = parent.getItem(index);
				if (e.type == SWT.MouseHover) {
					String tipText = "参数序号：" + index + "\r\n参 数 值："
							+ item.getText(1);

					textSql.setToolTipText(tipText);
				}
				if (e.type == SWT.MouseDown) {
					batchTree.setSelection(item);
					activateParamEdit();
				}
			}
		};
		textSql.addListener(SWT.MouseHover, textSqlListener);
		textSql.addListener(SWT.MouseDown, textSqlListener);
	}

	private void activateParamEdit() {
		// 打开参数编辑器
		if (batchTree.getSelectionCount() <= 0) {
			return;
		}
		TreeItem item = batchTree.getSelection()[0];
		if (item.getData() instanceof BatchItemInfo) {
			return;
		}
		treeEditor.setEditor(textParamEdit.getParent(), item, 1);
		textParamEdit.setText(item.getText(1));
		textParamEdit.selectAll();
		batchTree.update();

		// 定位指定参数的占位符'?'
		List<StyleRange> ranges = textSql.getStyleRangeByRule("placeSign");
		int index = item.getParentItem().indexOf(item);
		if (index < ranges.size()) {
			StyleRange range = ranges.get(index);
			textSql.setSelection(range.start, range.start + range.length);
		}
	}

	// 添加批处理项
	protected void doAddBatchItem() {
		InputDialog dlg = new InputDialog(shell, "添加处理项", "处理项名称描述", "处理项"
				+ (batchTree.getItemCount() + 1), new IInputValidator() {
			public String isValid(String newText) {
				if ("".equals(newText)) {
					return "请输入名称";
				}
				for (TreeItem ti : batchTree.getItems()) {
					if (ti.getText().equals(newText)) {
						return "名称不能重复";
					}
				}
				return null;
			}
		});
		if (dlg.open() != dlg.OK) {
			return;
		}
		try {
			BatchItemInfo info = (BatchItemInfo) JavaInfoUtils.createJavaInfo(
					batch.getEditor(),
					"com.zgw.fireline.base.widgets.BatchItem",
					new ConstructorCreationSupport(null, false));
			info.setName(dlg.getValue());
			TreeItem item = new TreeItem(batchTree, SWT.NONE);
			item.setText(1, dlg.getValue());
			item.setFont(SWTResourceManager.getFont("宋体", 9, SWT.BOLD));

			batchTree.setSelection(item);
			item.setData(info);
			textSql.setText("");
		} catch (Exception e) {
			throw ReflectionUtils.propagate(e);
		}
	}

	protected void doRemoveBatchItem() {
		if (batchTree.getSelectionCount() > 0)
			batchTree.getSelection()[0].dispose();
	}

	protected void doAddParam() {
		if (batchTree.getSelectionCount() > 0) {
			TreeItem selected = batchTree.getSelection()[0];
			TreeItem item;
			if (selected.getData() instanceof BatchItemInfo) {
				item = new TreeItem(selected, SWT.NONE);
			} else {
				item = new TreeItem(selected.getParentItem(), SWT.NONE);
			}
			batchTree.setSelection(item);
			activateParamEdit();
			textParamEdit.setFocus();
		}
	}

	protected void doRemoveParam() {
		if (batchTree.getSelectionCount() <= 0) {
			return;
		}
		TreeItem item = batchTree.getSelection()[0];
		if (item.getData() instanceof BatchItemInfo) {
			return;
		}
		item.dispose();
		treeEditor.getEditor().setVisible(false);
	}

	// 设置参数值
	protected void doSetParamValue() {
		if (batchTree.getSelectionCount() <= 0) {
			return;
		}
		TreeItem item = batchTree.getSelection()[0];
		if (item.getData() instanceof BatchItemInfo) {
			return;
		}
		ParamDialog dlg = new ParamDialog(shell, batch.getRootJava());
		Param param = (Param) item.getData(item.getText(1));
		dlg.param = param;
		if (dlg.open() == Window.OK) {
			item.setText(1, dlg.param.toString());
			textParamEdit.setText(item.getText(1));
			item.setData(item.getText(1), dlg.param);
			textParamEdit.setFocus();
			textParamEdit.selectAll();
			batchTree.update();
		}
	}

	protected void cancel() {
		result = SWT.CANCEL;
		shell.close();
	}

	protected void okPressed() {
		items.clear();
		for (TreeItem item : batchTree.getItems()) {
			if (item.getData() instanceof BatchItemInfo) {
				BatchItemInfo info = (BatchItemInfo) item.getData();
				Param[] params = new Param[item.getItemCount()];
				for (int i = 0; i < item.getItemCount(); i++) {
					String text = item.getItem(i).getText(1);
					params[i] = (Param) item.getItem(i).getData(text);
					if (params[i] == null) {
						params[i] = new Param();
						params[i].value = text;
					}
				}
				info.setParams(params);
				items.add(info);
			}
		}
		result = SWT.OK;
		shell.close();
	}

	// 执行提供器
	protected void doSearchExecProvide() {
		try {
			String className = JdtUiUtils.selectTypeName(shell, batch
					.getEditor().getJavaProject());
			if (className == null || className.trim().equals(""))
				return;
			Class<?> cla0 = GlobalState.getClassLoader().loadClass(className);
			Class<?> cla1 = GlobalState.getClassLoader().loadClass(
					"com.zgw.fireline.base.IDataBaseProvide");
			baseProvideClass = cla1.isAssignableFrom(cla0) ? cla0 : cla1;
			if (cla1.isAssignableFrom(cla0)) {
				baseProvideClass = cla0;
				setProvideClassText(className);
			} else {
				MessageDialog.openWarning(shell, "提示",
						"必须为IDataBaseProvide的实现类");
			}
		} catch (ClassNotFoundException e) {
			ExecutionUtils2.openErrorDialog("无法加载该类", e);
		} catch (Exception e) {
			DesignerPlugin.log(e);
		}
	}

	private void setProvideClassText(String className) {
		int i = 0;
		for (String s : execProvideComb.getItems()) {
			if (s.equals(className)) {
				execProvideComb.select(i);
				break;
			}
			i++;
		}
		if (i == execProvideComb.getItemCount()) {
			execProvideComb.add(className);
			execProvideComb.select(i);
		}
	}
}
